//
//  UIImage+Extension.swift
//  TrustHost
//
//  Created by 好东家 on 2021/6/4.
//

import UIKit


extension UIImage {
    
    
    /// 图片简单染色，保留透明度
    public func tinted(with color: UIColor) -> UIImage? {
        UIGraphicsBeginImageContextWithOptions(size, false, scale)
        defer { UIGraphicsEndImageContext() }
        
        color.setFill()
        let rect = CGRect(origin: .zero, size: size)
        UIRectFill(rect)
        
        draw(in: rect, blendMode: .destinationIn, alpha: 1.0)
        
        return UIGraphicsGetImageFromCurrentImageContext()
    }
    
    /// 按角度旋转图片 opaque: 图片是否是不透明的，不透明的性能更高
    public func rotated(byDegrees degrees: CGFloat,opaque: Bool = true) -> UIImage? {
        // 处理0度和360度的情况，直接返回原图
        let normalizedDegrees = degrees.truncatingRemainder(dividingBy: 360)
        if normalizedDegrees == 0 {
            return self
        }
        
        let radians = normalizedDegrees * .pi / 180
        
        // 计算旋转后图片的包围矩形大小
        let rotatedSize = CGRect(origin: .zero, size: self.size)
            .applying(CGAffineTransform(rotationAngle: radians))
            .integral.size
        
        let format = UIGraphicsImageRendererFormat()
        format.scale = self.scale
        format.opaque = opaque
        
        let renderer = UIGraphicsImageRenderer(size: rotatedSize, format: format)
        
        return renderer.image { context in
            // 将坐标系移动到画布中心
            context.cgContext.translateBy(x: rotatedSize.width / 2,
                                         y: rotatedSize.height / 2)
            // 旋转坐标系
            context.cgContext.rotate(by: radians)
            
            // 绘制图片，坐标系原点在中心，左上角要偏移图片宽高一半
            self.draw(in: CGRect(x: -self.size.width / 2,
                                y: -self.size.height / 2,
                                width: self.size.width,
                                height: self.size.height))
        }
    }
    
    
    /// 取图片中间部分
    public func centerSquareCropped() -> UIImage? {
        guard let cgImage = cgImage else { return nil }
        let length = min(cgImage.width, cgImage.height)
        let x = (cgImage.width - length) / 2
        let y = (cgImage.height - length) / 2
        let cropRect = CGRect(x: x, y: y, width: length, height: length)
        
        guard let croppedCGImage = cgImage.cropping(to: cropRect) else { return nil }
        return UIImage(cgImage: croppedCGImage, scale: scale, orientation: imageOrientation)
    }
    
    
    public func cropByDrawing(in rect: CGRect) -> UIImage? {
        UIGraphicsBeginImageContextWithOptions(rect.size, false, scale)
        defer { UIGraphicsEndImageContext() }
        
        let drawRect = CGRect(
            x: -rect.origin.x,
            y: -rect.origin.y,
            width: size.width,
            height: size.height
        )
        
        draw(in: drawRect)
        return UIGraphicsGetImageFromCurrentImageContext()
    }
    
    
    // 截取图片指定区域
    public func cropped(to rect: CGRect) -> UIImage? {
        let scale = self.scale
        let imageHeight = self.size.height * self.scale
        let imageWidth = self.size.width * self.scale
        // CGImage 坐标系原点在左下角，需转换 UIKit 坐标系
        let scaledRect = CGRect(
            x: rect.origin.x * scale,
            y: (imageHeight - rect.origin.y * scale - rect.height * scale),
            width: rect.width * scale,
            height: rect.height * scale
        )
        
        var transform = CGAffineTransform.identity
        switch self.imageOrientation {
        case .left:
            transform = CGAffineTransform(rotationAngle: .pi/2).translatedBy(x: 0, y: -imageHeight)
        case .right:
            transform = CGAffineTransform(rotationAngle: -.pi/2).translatedBy(x: -imageWidth, y: 0)
        case .down:
            transform = CGAffineTransform(rotationAngle: .pi).translatedBy(x: -imageWidth, y: -imageHeight)
        default:
            break
        }
        let tageRect = scaledRect.applying(transform)
        
        guard let cgImage = self.cgImage?.cropping(to: tageRect) else { return nil }
        return UIImage(cgImage: cgImage, scale: scale, orientation: self.imageOrientation)
    }
    
    
    
// MARK: 根据尺寸重新生成图片
    /// 根据尺寸重新生成图片
    /// - Parameter size: 设置的大小
    /// - Returns: 新图
    public static func imageWithNewSize(image:UIImage ,size: CGSize) -> UIImage? {
     
        if image.size.height > size.height {
             
             let width = size.height / image.size.height * image.size.width
             
             let newImgSize = CGSize(width: width, height: size.height)
             
             UIGraphicsBeginImageContext(newImgSize)
             
            image.draw(in: CGRect(x: 0, y: 0, width: newImgSize.width, height: newImgSize.height))
             
             let theImage = UIGraphicsGetImageFromCurrentImageContext()
             
             UIGraphicsEndImageContext()
             
             guard let newImg = theImage else { return  nil}
             
             return newImg
             
         } else {
             
             let newImgSize = CGSize(width: size.width, height: size.height)
             
             UIGraphicsBeginImageContext(newImgSize)
             
            image.draw(in: CGRect(x: 0, y: 0, width: newImgSize.width, height: newImgSize.height))
             
             let theImage = UIGraphicsGetImageFromCurrentImageContext()
             
             UIGraphicsEndImageContext()
             
             guard let newImg = theImage else { return  nil}
             
             return newImg
         }
     
     }
    
    
// MARK: 图片压缩

    
    public func compressImageWithEstimatedQuality(toMaxSizeKB maxSizeKB: Int) -> Data? {
        
        let image = self
        let maxSize = maxSizeKB * 1024
        
        // 获取原图最大质量JPEG数据
        guard let originalData = image.jpegData(compressionQuality: 1.0) else { return nil }
        let originalSize = originalData.count
        
        // 如果已经小于目标大小，直接返回
        if originalSize <= maxSize {
            return originalData
        }
        
        // 估计压缩质量比例
        var estimatedQuality = CGFloat(maxSize) / CGFloat(originalSize)
        estimatedQuality = min(max(estimatedQuality, 0.01), 1.0) // 限制范围0.01~1.0
        
        // 从估计值开始压缩
        var compression: CGFloat = estimatedQuality
        var compressedData = image.jpegData(compressionQuality: compression)
        
        // 循环尝试降低压缩质量，直到满足大小要求或者压缩质量过低
        while let data = compressedData, data.count > maxSize && compression > 0.01 {
            compression -= 0.05
            compressedData = image.jpegData(compressionQuality: compression)
        }
        
        return compressedData
    }


    
    
    
    
    
    
// MARK: 图片拉伸
    ///对指定图片进行拉伸
    public func resizableImage(name: String) -> UIImage {
        
        var normal = UIImage(named: name)!
        let imageWidth = normal.size.width * 0.5
        let imageHeight = normal.size.height * 0.5
        normal = resizableImage(withCapInsets: UIEdgeInsets(top: imageHeight, left: imageWidth, bottom: imageHeight, right: imageWidth))
        
        return normal
    }
    
    
// MARK: 压缩图片到指定字节
    /**
     *  压缩上传图片到指定字节
     *  image     压缩的图片
     *  maxLength 压缩后最大字节大小
     *  return 压缩后图片的二进制
     */
    public func compressImage(image: UIImage, maxLength: Int) -> NSData? {
        
        let newSize = self.scaleImage(image: image, imageLength: 300)
        let newImage = self.resizeImage(image: image, newSize: newSize)
        
        var compress:CGFloat = 1.0
        var data = newImage.jpegData(compressionQuality: compress)
        
        while (data?.count)! > maxLength && compress > 0.01 {
            compress -= 0.02
            data = newImage.jpegData(compressionQuality: compress)
        }
        
        return data as NSData?
    }
    
    
// MARK: 通过指定图片最长边，获得等比例的图片size
    /**
     *  通过指定图片最长边，获得等比例的图片size
     *  image       原始图片
     *  imageLength 图片允许的最长宽度（高度）
     *  return 获得等比例的size
     */
    public func  scaleImage(image: UIImage, imageLength: CGFloat) -> CGSize {
        
        var newWidth:CGFloat = 0.0
        var newHeight:CGFloat = 0.0
        let width = image.size.width
        let height = image.size.height
    
        if (width > imageLength || height > imageLength){
            
            if (width > height) {
                
                newWidth = imageLength;
                newHeight = newWidth * height / width;
                
            }else if(height > width){
                
                newHeight = imageLength;
                newWidth = newHeight * width / height;
                
            }else{
                
                newWidth = imageLength;
                newHeight = imageLength;
            }
            
        }
        return CGSize(width: newWidth, height: newHeight)
    }
    
    
// MARK: 获得指定size的图片
    /**
     *  获得指定size的图片
     *  image   原始图片
     *  newSize 指定的size
     *  return 调整后的图片
     */
    public func resizeImage(image: UIImage, newSize: CGSize) -> UIImage {
        UIGraphicsBeginImageContext(newSize)
        image.draw(in: CGRect(x: 0, y: 0, width: newSize.width, height: newSize.height))
        
        let newImage = UIGraphicsGetImageFromCurrentImageContext()
        UIGraphicsEndImageContext()
        
        return newImage!
    }

    
    
// MARK: 颜色转图片
    ///颜色转图片
    public func colorFromImage(image:UIImage) -> UIColor {
        return UIColor.init(patternImage: image)
    }
    
    
// MARK: 添加水印/图片层叠
    ///添加水印/图片层叠
    public func imageAddLogo(logo:UIImage) -> UIImage {
        let w = self.size.width
        let h = self.size.height
        let logoWidth = logo.size.width
        let logoHeight = logo.size.height
        
        let colorSpace = CGColorSpaceCreateDeviceRGB()
        let context = CGContext(data: nil, width: Int(w), height: Int(h), bitsPerComponent: 8, bytesPerRow: 44 * Int(w), space: colorSpace,bitmapInfo: CGImageAlphaInfo.premultipliedFirst.rawValue )
        context?.draw(self.cgImage!, in: CGRect.init(x: 0, y: 0, width: w, height: h))
        context?.draw(logo.cgImage!, in: CGRect.init(x: w - logoWidth - 15, y: 10, width: logoWidth, height: logoHeight))
        let imageMasked = context!.makeImage()
        let returnImage = UIImage.init(cgImage: imageMasked!)
        return returnImage
    }
    
// MARK: 叠加图片
    /// 叠加图片
    /// - Parameters:
    ///   - fillImage: 中间的icon图片
    ///   - fillSize: icon的大小
    /// - Returns: 合成后的图片
    public func superpositionfillImage(_ fillImage:UIImage?,_ fillSize:CGSize) -> UIImage? {
        let input = self
       guard let fill = fillImage  else {
           return self
       }
       let imageSize = input.size
       UIGraphicsBeginImageContext(imageSize)
       input.draw(in: CGRect.init(x: 0, y: 0, width: imageSize.width, height: imageSize.height))
       let fillWidth = min(imageSize.width, fillSize.width)
       let fillHeight = min(imageSize.height, fillSize.height)
       let fillRect = CGRect(x: (imageSize.width - fillWidth)/2, y: (imageSize.height - fillHeight)/2, width: fillWidth ,height: fillHeight)
       fill.draw(in: fillRect)
       guard let newImage = UIGraphicsGetImageFromCurrentImageContext() else {
           UIGraphicsEndImageContext()
           return self
       }
       UIGraphicsEndImageContext()
       return newImage
    }
    
    
    
}
